<?php
/**
 * | 节程 [ 节程赋能开发者，助力企业发展 ]
 * +----------------------------------------------------------------------
 *  | Copyright (c) 2020~2029 温州惊蛰网络科技有限公司 All rights reserved.
 * +----------------------------------------------------------------------
 *  | Licensed 节程并不是自由软件，未经许可不能去掉节程相关版权
 * +----------------------------------------------------------------------
 */


namespace app\shop_admin\service;

use app\shop_admin\model\Order;
use app\shop_admin\model\ReceiptsPrinter;
use app\shop_admin\model\ReceiptsTask;
use app\shop_admin\model\ReceiptsTemplate;
use app\utils\Receipts;
use think\Exception;
use think\facade\Db;

class ReceiptsService extends Receipts
{
    private $user;
    public function __construct()
    {
        global $user;
        if(!\app\utils\Addons::check($user->mall_id,10))
            throw new Exception('请先激活小票助手相关插件',HTTP_SUCCESS);
        $this->user = $user;
    }
    //------------------------------------------模板相关方法-------------------------------------------------------------

    /**
     * 模板列表
     * @param int $merchant_id
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function list_template(int $merchant_id) : array{
        $list = ReceiptsTemplate::where('merchant_id',$merchant_id)
            ->order('default DESC')
            ->select();
        return [HTTP_SUCCESS,$list];
    }

    /**
     * 模板详情
     * @param int $id
     * @return array
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function find_template(int $id) : array{
        $find = ReceiptsTemplate::find($id);
        if (empty($find))
            throw new Exception('模板不存在',HTTP_INVALID);
        return [HTTP_SUCCESS,$find];
    }

    /**
     * 默认模板
     * @param int $id
     * @param int $merchant_id
     * @return array
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function default_template(int $id, int $merchant_id) : array {
        $template = ReceiptsTemplate::find($id);
        if (empty($template))
            throw new Exception('模板不存在',HTTP_INVALID);
        Db::name('receipts_template')
            ->where('merchant_id',$merchant_id)
            ->update(['default' => 0]);
        $template->save(['default' => 1]);
        return [HTTP_SUCCESS,'修改成功'];
    }

    /**
     * 创建模板
     * @param array $config
     * @param int $merchant_id
     * @return array
     * @throws Exception
     */
    public function create_template(array $config,string $name, int $merchant_id) : array{
        $data = [
            'merchant_id' => $merchant_id,
            'name' => $name,
            'config' => json_encode($config,JSON_NUMERIC_CHECK),
            'mall_id' => $this->user->mall_id,
            'create_time' => date('Y-m-d H:i:s')
        ];
        $count = ReceiptsTemplate::where('merchant_id',$merchant_id)
            ->where('default',1)
            ->count();
        if ($count == 0)
            $data['default'] = 1;
        $template = ReceiptsTemplate::create($data);
        if (empty($template->id))
            throw new Exception('添加模板失败',HTTP_INVALID);
        return [HTTP_SUCCESS,$template];
    }

    /**
     * 更新模板
     * @param array $config
     * @param int $id
     * @return array
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function update_template(array $config,?string $name, int $id) : array{
        $template = ReceiptsTemplate::find($id);
        if (empty($template))
            throw new Exception('模板不存在',HTTP_INVALID);
        $data = ['config' => json_encode($config,JSON_NUMERIC_CHECK)];
        if (!empty($name))
            $data['name'] = $name;
        $is_bool = $template->save($data);
        if ($is_bool)
            return [HTTP_SUCCESS, '更新成功'];
        return [HTTP_INVALID,'更新失败'];
    }

    /**
     * 删除模板
     * @param int $id
     * @return array
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function delete_template(int $id) : array{
        $template = ReceiptsTemplate::find($id);
        if (empty($template))
            throw new Exception('模板不存在',HTTP_INVALID);
        $template->delete();
        return [HTTP_SUCCESS,'删除成功'];
    }
    //------------------------------------------打印机相关操作-----------------------------------------------------------

    /**
     * 打印机列表
     * @param int $merchant_id
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function list_printer(int $merchant_id) : array{
        $list = ReceiptsPrinter::where('merchant_id',$merchant_id)
            ->order('default DESC')
            ->select();
        return [HTTP_SUCCESS,$list];
    }

    /**
     * 打印机详情
     * @param int $id
     * @return array
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function find_printer(int $id) : array{
        $printer = ReceiptsPrinter::find($id);
        if (empty($printer))
            throw new Exception('打印机不存在',HTTP_INVALID);
        return [HTTP_SUCCESS,$printer];
    }

    /**
     * 添加打印机
     * @param string $code
     * @param string $client_id
     * @param string $client_secret
     * @param int $merchant_id
     * @return array
     */
    public function insert_printer(string $name,string $printer_no, string $client_id, string $client_secret,string $printer_secret, int $merchant_id) : array{
        $data = [
            'name' => $name,
            'printer_no' => $printer_no,
            'client_id' => $client_id,
            'client_secret' => $client_secret,
            'printer_secret' => $printer_secret,
            'create_time' => date('Y-m-d H:i:s'),
            'merchant_id' => $merchant_id,
            'mall_id' => $this->user->mall_id
        ];
        $count = ReceiptsPrinter::where('merchant_id',$merchant_id)
            ->where('default',1)
            ->count();
        if ($count == 0)
            $data['default'] = 1;
        $printer = ReceiptsPrinter::create($data);
        return [HTTP_SUCCESS,$printer];
    }

    /**
     * 更新打印机
     * @param int $id
     * @param string $code
     * @param string $client_id
     * @param string $client_secret
     * @return array
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function update_printer(int $id,array $data) : array{
        $printer = ReceiptsPrinter::find($id);
        if (empty($printer))
            throw new Exception('打印机不存在',HTTP_INVALID);
        $data['update_time'] = date('Y-m-d H:i:s');
        $is_bool = $printer->save($data);
        if ($is_bool)
            return [HTTP_SUCCESS,'更新成功'];
        return [HTTP_INVALID,'更新失败'];
    }

    /**
     * 删除打印机
     * @param int $id
     * @return array
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function delete_printer(int $id) : array{
        $printer = ReceiptsPrinter::find($id);
        if (empty($printer))
            throw new Exception('打印机不存在',HTTP_INVALID);
        $printer->delete();
        return [HTTP_SUCCESS,'删除成功'];
    }

    /**
     * 默认打印机
     * @param int $id
     * @param int $merchant_id
     * @return array
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function default_printer(int $id, int $merchant_id) : array{
        $printer = ReceiptsPrinter::find($id);
        if (empty($printer))
            throw new Exception('模板不存在',HTTP_INVALID);
        Db::name('receipts_printer')
            ->where('merchant_id',$merchant_id)
            ->update(['default' => 0]);
        $printer->save(['default' => 1]);
        return [HTTP_SUCCESS,'修改成功'];
    }
    //------------------------------------------打印计划相关操作----------------------------------------------------------

    /**
     * @param int $page
     * @param int $size
     * @return array
     * @throws \think\db\exception\DbException
     */
    public function list_task(int $merchant_id) : array{
        $list = ReceiptsTask::where('merchant_id',$merchant_id)->select();
        return [HTTP_SUCCESS,$list];
    }

    /**
     * @param int $id
     * @return array
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function find_task(int $id) : array{
        $task = ReceiptsTask::find($id);
        if (empty($task))
            throw new Exception('计划不存在',HTTP_INVALID);
        return [HTTP_SUCCESS,$task];
    }

    /**
     * @param array $post
     * @param int $merchant_id
     * @return array
     */
    public function create_task(array $post, int $merchant_id) : array{
        $post['configure'] = json_encode($post['configure'],JSON_NUMERIC_CHECK);
        $post['create_time'] = date('Y-m-d H:i:s');
        $post['merchant_id'] = $merchant_id;
        $post['mall_id'] = $this->user->mall_id;

        $task = ReceiptsTask::create($post);
        $is_bool = !empty($task['id']);
        if ($is_bool)
            return [HTTP_SUCCESS,'创建成功'];
        return [HTTP_INVALID,'创建失败'];
    }

    /**
     * @param int $id
     * @param array $put
     * @return array
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function update_task(int $id, array $put) : array{
        if(!empty($put['configure']))
            $put['configure'] = json_encode($put['configure'],JSON_NUMERIC_CHECK);
        $put['update_time'] = date('Y-m-d H:i:s');
        $task = ReceiptsTask::find($id);
        if (empty($task))
            throw new Exception('计划不存在',HTTP_INVALID);
        $is_bool = $task->save($put);
        if ($is_bool)
            return [HTTP_SUCCESS, '更新成功'];
        return [HTTP_INVALID,'更新失败'];
    }

    /**
     * @param int $id
     * @return array
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function delete_task(int $id) : array{
        $task = ReceiptsTask::find($id);
        if (empty($task))
            throw new Exception('计划不存在',HTTP_INVALID);
        $is_bool = $task->delete(true);
        if ($is_bool)
            return [HTTP_SUCCESS, '删除成功'];
        return [HTTP_INVALID,'删除失败'];
    }

    /**
     * 执行打印计划
     * @param array $order_id
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function implementation_plan(array $order_id,string $type) : void{
        global $user;
        $select = ReceiptsTask::where('mall_id',$user['mall_id'])->select();
        $task = $store = [];
        foreach ($select AS $key => $value)
            $task[$value->id] = $value;
        if (!empty($task)){
            foreach ($task AS $key => $value) {
                $configure = json_decode($value->configure);
                if (empty($type) || empty($configure->$type))continue;
                $this->create($value->template_id, $order_id, $value->printer_id, $value->type, $value->store_id);
            }
        }
    }

    /**
     * @param int $template_id
     * @param array $order_id
     * @param int $merchant_id
     * @return array
     * @throws Exception
     */
    public function create(int $template_id, array $order_id,int $printer,int $type,?int $store) : void{
        $this->setOrder($order_id);
        $this->remote();
        $this->setConfig($printer);
        foreach ($this->order AS $key) {
            if (!empty($type)){
                $order2 = $key;
                $order_commodity = $order_commodity2 = $key->order_commodity->toArray();
                if ($type == 2) {
                    $store_id = array_column($order_commodity, 'store_id');
                    if (!in_array($store, $store_id)) continue;
                    foreach ($order_commodity AS $index => $item) {
                        if (!empty($store)) {
                            if ($item['store_id'] != $store) {
                                unset($order_commodity2[$index]);
                                unset($order2->order_commodity[$index]);
                            }
                        }
                        if ($item['type'] != 2){
                            if (!empty($order_commodity2[$index]))unset($order_commodity2[$index]);
                            if (!empty($order2->order_commodity[$index]))unset($order2->order_commodity[$index]);
                        }
                    }
                }else{
                    foreach ($order_commodity AS $index => $item) {
                        if ($item['type'] != 1){
                            unset($order_commodity2[$index]);
                            unset($order2->order_commodity[$index]);
                        }
                    }
                }
                if (empty($order_commodity2))continue;
            }
            $post['client_id'] = $this->client_id;
            $post['machine_code'] = $this->machine_code;
            $post['content'] = $this->getContent($template_id,$order2 ?? $key);
            $post['origin_id'] = $key->order_no;
            $post['timestamp'] = time();
            $post['id'] = md5(uniqid().rand(1000,9999));
            $post['access_token'] = $this->getAccessToken($post);
            $post['sign'] = $this->getSign($post);
            $this->post($post, $this->printf_url);
        }
    }

    /**
     * @param array $order_id
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    protected function setOrder(array $order_id) : void {
        $this->order = Order::where('id','IN',$order_id)
            ->with([
                'order_commodity' => function($sql){
                    $sql->field('o.id,o.money,o.type,o.count,o.receiving_time,o.money,o.order_id,(CASE WHEN o.sku_id IS NULL THEN c.name ELSE CONCAT(c.name,\'(\',(select pvs_value FROM jiecheng_sku WHERE id=o.sku_id),\')\') END) AS name,`group`')
                        ->alias('o')
                        ->join('commodity c','c.id=o.commodity_id','left');
                    },
                'user' => function($sql){
                    $sql->field('id,nickname,name,mobile');
                }])
            ->select();
        if (empty($this->order))
            throw new Exception('订单不存在',HTTP_INVALID);
    }

}